﻿--MacaroonLoot, a World of Warcraft® user interface addon.
--Copyright© 2008 Connor H. Chenoweth, aka Maul

Macaroon.LootBars = {}
Macaroon.LootButtons = {}

MacaroonLootSavedState = {}

local lootElements = {}
local addonData, sortData = {}

local currentVersion = 30000.11
local load, ss, playerEnteredWorld

local lower = string.lower
local sort = table.sort
local format = string.format

local copyTable = Macaroon.copyTable
local clearTable = Macaroon.clearTable
local getChildrenAndRegions = Macaroon.getChildrenAndRegions

local function groupLootFrame_OnShow(self)

	if (not self.rollID) then return end

	local texture, name, count, quality, bindOnPickUp = GetLootRollItemInfo(self.rollID);

	if ( bindOnPickUp ) then
		self:SetBackdrop({bgFile = "Interface\\DialogFrame\\UI-DialogBox-Gold-Background", edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Gold-Border", tile = true, tileSize = 32, edgeSize = 32, insets = { left = 11, right = 12, top = 12, bottom = 11 } } );
		getglobal(self:GetName().."Corner"):SetTexture("Interface\\DialogFrame\\UI-DialogBox-Gold-Corner");
		getglobal(self:GetName().."Decoration"):Show();
	else
		self:SetBackdrop({bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background", edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border", tile = true, tileSize = 32, edgeSize = 32, insets = { left = 11, right = 12, top = 12, bottom = 11 } } );
		getglobal(self:GetName().."Corner"):SetTexture("Interface\\DialogFrame\\UI-DialogBox-Corner");
		getglobal(self:GetName().."Decoration"):Hide();
	end

	local id = self:GetID();
	getglobal("GroupLootFrame"..id.."IconFrameIcon"):SetTexture(texture);
	getglobal("GroupLootFrame"..id.."Name"):SetText(name);
	local color = ITEM_QUALITY_COLORS[quality];
	getglobal("GroupLootFrame"..id.."Name"):SetVertexColor(color.r, color.g, color.b);
end

GroupLootFrame_OnShow = groupLootFrame_OnShow

local function groupLootFrame_OnEvent(self, event, ...)

	if (not self.rollID) then return end

	if ( event == "CANCEL_LOOT_ROLL" ) then
		local arg1 = ...;
		if ( arg1 == self.rollID ) then
			self:Hide();
			StaticPopup_Hide("CONFIRM_LOOT_ROLL", self.rollID);
		end
	end
end

GroupLootFrame_OnEvent = groupLootFrame_OnEvent

local function groupLootFrame_OnUpdate(self, elapsed)

	if (not self:GetParent().rollID) then return end

	local left = GetLootRollTimeLeft(self:GetParent().rollID);
	local min, max = self:GetMinMaxValues();
	if ( (left < min) or (left > max) ) then
		left = min;
	end
	self:SetValue(left);
end

GroupLootFrame_OnUpdate = groupLootFrame_OnUpdate

local function updateButtonData(button, bar, state)

	button.bar = bar
	button.alpha = bar.config.alpha
	button.showGrid = bar.config.showGrid
	button:SetAttribute("showgrid-bar", bar.config.showGrid)
	button.config.showstates = state
	button:SetAttribute("showstates", state)

	button.skincolor = bar.config.skincolor
	button.rangecolor = bar.config.rangecolor
	button.manacolor = bar.config.manacolor
	button.buffcolor = bar.config.buffcolor
	button.debuffcolor = bar.config.debuffcolor
	button.hovercolor = bar.config.hovercolor
	button.equipcolor = bar.config.equipcolor
	button.cdcolor1 = bar.config.cdcolor1
	button.cdcolor2 = bar.config.cdcolor2
	button.bdcolor1 = bar.config.bdcolor1
	button.bdcolor2 = bar.config.bdcolor2

	button.config.bar = bar:GetID()
	button.config.stored = false

	button:SetFrameStrata(bar.config.buttonStrata)

	button:SetFrameLevel(4)

	if (bar.handler) then
		Macaroon.UpdateButtonVisibility(button, bar.handler:GetAttribute("state-current"))
	end
end

local function buttonDefaults(index, button)

	button.config = {
		bar = 0,
		barPos = 0,
		showstates = "",
		laststate = "",
		hotKeys = ":",
		hotKeyText = ":",
		hotKeyLock = false,
		scale = 1,
		XOffset = 0,
		YOffset = 0,
		mouseoverAnchor = false,
		clickAnchor = false,
		anchorDelay = "0.1",
		anchoredBar = "",
	}
end

local function createLootButton(index)

	local button

	if (_G["MacaroonLootButton"..index]) then
		button = _G["MacaroonLootButton"..index]
	else
		button = CreateFrame("CheckButton", "MacaroonLootButton"..index, UIParent, "MacaroonAnchorButtonTemplate")
	end

	local buttonName = button:GetName()
	local objects = getChildrenAndRegions(button)

	for k,v in pairs(objects) do
		local name = gsub(v, button:GetName(), "")
		button[lower(name)] = _G[v]
	end

	button:SetID(index)
	button.id = index
	button:SetWidth(lootElements[index]:GetWidth()+1)
	button:SetHeight(lootElements[index]:GetHeight()+1)
	button:SetHitRectInsets(button:GetWidth()/2, button:GetWidth()/2, button:GetHeight()/2, button:GetHeight()/2)

	button.editframe:SetPoint("TOPLEFT")
	button.editframe:SetPoint("BOTTOMRIGHT")
	button.editframetype:SetText("loot")

	buttonDefaults(index, button)
	button.lootelement = lootElements[index]

	objects = getChildrenAndRegions(button.lootelement)

	for k,v in pairs(objects) do
		local name = gsub(v, button.lootelement:GetName(), "")
		button[lower(name)] = _G[v]
	end

	button.lootelement:ClearAllPoints()
	button.lootelement:SetParent(button)
	button.lootelement:SetPoint("CENTER", button, "CENTER")
	button.lootelement:SetScale(1)

	button.updateButtonData = updateButtonData

	button:SetAttribute("showgrid", 0)
	button:SetAttribute("showstates", "")
	button:SetAttribute("hotkeys", "")
	button:SetAttribute("hasaction", true)
	button:SetAttribute("_childupdate", [[

			self:SetAttribute("stateshown", false)

			for showstate in gmatch(self:GetAttribute("showstates"), "[^;]+") do
				if (message and strfind(message, showstate)) then
					if (self:GetAttribute("hasaction") or self:GetAttribute("showgrid-bar") or self:GetAttribute("editmode")) then
						self:Show()
					end
					self:SetAttribute("stateshown", true)
				end
			end

			if (not self:GetAttribute("stateshown")) then
				self:Hide()
			end
		]] )


	if (not ss["loot"]) then
		ss["loot"] = {}
	end

	ss["loot"][index] = { button.config }

	Macaroon.LootButtons[index] = { button, 1 }

	return button
end

local function updateVariables(element, defaultConfig)

	-- Add new vars
	for key,value in pairs(defaultConfig) do

		if (element.config[key] == nil) then

			if (element.config[lower(key)] ~= nil) then

				element.config[key] = element.config[lower(key)]
				element.config[lower(key)] = nil
			else
				element.config[key] = value
			end
		end
	end
	-- Add new vars

	-- Kill old vars
	for key,value in pairs(element.config) do
		if (defaultConfig[key] == nil) then
			element.config[key] = nil
		end
	end
	-- Kill old vars
end

local function lootbarUpdate(bar, state)

	if (bar:IsVisible()) then
		for k,v in pairs(lootElements) do
			v:Show()
		end
	else
		for k,v in pairs(lootElements) do
			v:Hide()
		end
	end
end

function Macaroon.LootLoadSavedData(saved, profile)

	if (saved) then

		load = true

		local savedState = copyTable(saved)
		local newBar, defaultConfig = false

		if (savedState.lootbars) then

			clearTable(Macaroon.LootBars)

			defaultConfig = Macaroon.GetBarDefaults()

			for k,v in pairs(savedState.lootbars) do

				local bar = Macaroon.CreateBar("loot", true, true)

				bar.config = copyTable(savedState.lootbars[k][1])

				updateVariables(bar, defaultConfig)

				bar.handler:SetAttribute("state-current", bar.config.currentstate)

				bar.handler:SetAttribute("state-last", bar.config.laststate)

				bar.updateFunc = lootbarUpdate

			end

			savedState.lootbars = nil

		elseif (not profile) then

			newBar = Macaroon.CreateBar("loot", true, true)
		end

		if (savedState.loot) then

			for k,v in pairs(Macaroon.LootButtons) do
				Macaroon.StoreButton(v[1], Macaroon.LootButtons)
			end

			defaultConfig = Macaroon.GetLootButtonDefaults()

			for k,v in pairs(savedState.loot) do

				local button = createLootButton(k)

				button.config = copyTable(savedState.loot[k][1])

				updateVariables(button, defaultConfig)
			end

			savedState.loot = nil

		elseif (not profile) then

			for k,v in ipairs(lootElements) do
				createLootButton(k)
			end
		end

		if (newBar) then
			Macaroon.AddButton(#lootElements, newBar)
		end

		if (newBar) then
			Macaroon.Ypos = Macaroon.UpdateBarPositions(Macaroon.LootBars, true, Macaroon.Ypos)
		end

		for k,v in pairs(savedState) do
			if (ss[k]) then
				ss[k] = v
			end
		end
	end
end

function Macaroon.LootUpdateElements()

	for k,v in pairs(Macaroon.LootBars) do

		v.stateschanged = true

		v.buttonCountChanged = true

		v.updateBar(v, true, true, true, true)
	end

	for k,v in pairs(Macaroon.LootBars) do

		v.updateBarLink(v)
	end
end

function Macaroon.LootSaveCurrentState()

	if (load) then

		if (ss.lootbars) then
			clearTable(ss.lootbars)
		else
			ss.lootbars = {}
		end

		for k,v in pairs(Macaroon.LootBars) do
			ss.lootbars[k] = { v.config }
		end

		if (ss.loot) then
			clearTable(ss.loot)
		else
			ss.loot = {}
		end

		for k,v in pairs(Macaroon.LootButtons) do
			ss.loot[k] = { v[1].config }
		end

		ss.savedVersion = currentVersion
	end

	return ss, "lootbars", "loot"
end

function Macaroon.LootBarDefaults(bar)

	bar.config.name = "Loot Bar "..bar:GetID()
	bar.config.columns = 1

	bar.updateFunc = lootbarUpdate

	bar.handler:SetAttribute("state-current", bar.config.currentstate)
	bar.handler:SetAttribute("state-last", bar.config.laststate)
end

function Macaroon.GetLootButtonDefaults()

	local defaults = {}

	buttonDefaults(0, defaults)

	return defaults.config
end

function Macaroon.AddLootButton(bar)
	-- do nothing
end

function Macaroon.LootSetSaved()

	if (MacaroonSavedState.useShared and MacaroonSharedSavedState[MacaroonSavedState.sharedProfile]) then
		ss = MacaroonSharedSavedState[MacaroonSavedState.sharedProfile]

		if (not ss) then
			ss = MacaroonLootSavedState
		end
	else
		ss = MacaroonLootSavedState
	end

	return ss
end

local function controlOnEvent(self, event, ...)

	if (event == "VARIABLES_LOADED") then

		Macaroon.LootSetSaved()

		for i=NUM_GROUP_LOOT_FRAMES,1,-1 do
			lootElements[i] = _G["GroupLootFrame"..i]
		end

		UIPARENT_MANAGED_FRAME_POSITIONS.GroupLootFrame1 = nil

		Macaroon.CreateBarTypes.loot = { "Lootbars", ss, Macaroon.LootBars, Macaroon.LootButtons, "MacaroonLootButton", Macaroon.AddLootButton, Macaroon.LootBarDefaults, "6Loot Bar" }

		Macaroon.StatesToSave.loot = Macaroon.LootSaveCurrentState
		Macaroon.SavedDataLoad.loot = Macaroon.LootLoadSavedData
		Macaroon.SavedDataUpdate.loot = Macaroon.LootUpdateElements
		Macaroon.SetSavedVars.loot = Macaroon.LootSetSaved

	elseif (event == "PLAYER_LOGIN") then

		Macaroon.LootLoadSavedData(ss)

	elseif (event == "PLAYER_ENTERING_WORLD" and not playerEnteredWorld) then

		Macaroon.LootUpdateElements()

		playerEnteredWorld = true

	end
end

local frame = CreateFrame("Frame", nil, UIParent)
frame:SetScript("OnEvent", controlOnEvent)
frame:RegisterEvent("VARIABLES_LOADED")
frame:RegisterEvent("PLAYER_LOGIN")
frame:RegisterEvent("PLAYER_ENTERING_WORLD")